using System;
using System.Web.UI;
using FubuMVC.Core.Runtime;
using NUnit.Framework;
using FubuMVC.Core.View;
using FubuMVC.Core.View.WebForms;
using Rhino.Mocks;

namespace FubuMVC.Tests.View.WebForms
{
    [TestFixture]
    public class WebFormsViewRendererTester
    {
        private WebFormsViewRenderer _renderer;
        private IWebFormsControlBuilder _builder;
        private TestControl _control;
        private string _expectedVirtualPath;
        private string _expectedRendering;
        private Type _expectedType;
        private IModelState _modelState;

        [SetUp]
        public void SetUp()
        {
            _control = new TestControl();
            _modelState = MockRepository.GenerateStub<IModelState>();
            _builder = MockRepository.GenerateMock<IWebFormsControlBuilder>();
            _renderer = new WebFormsViewRenderer(_modelState, _builder);

            _expectedType = typeof(IFubuView);

            _expectedVirtualPath = "EXPECTED";
            _expectedRendering = "EXPECTED RENDER";

            _builder.Stub(b => b.LoadControlFromVirtualPath(_expectedVirtualPath, _expectedType)).Return(_control);
            _builder.Stub(b => b.ExecuteControl(_control)).Return(_expectedRendering);
        }

        [Test]
        public void should_use_selector_strategy_to_get_view_path()
        {
            _renderer.RenderView(_expectedVirtualPath);
            _builder.AssertWasCalled(b => b.LoadControlFromVirtualPath(_expectedVirtualPath, _expectedType));
        }

        [Test]
        public void should_set_up_viewmodel_on_page_if_present()
        {
            _renderer.RenderView(_expectedVirtualPath);
            _control.StateThatWasSet.ShouldBeTheSameAs(_modelState);
        }

        [Test]
        public void should_execute_control()
        {
            _renderer.RenderView(_expectedVirtualPath);

            _builder.AssertWasCalled(b => b.ExecuteControl(_control));
        }

        [Test]
        public void should_return_render_output()
        {
            _renderer.RenderView(_expectedVirtualPath).ShouldEqual(_expectedRendering);
        }

        private class TestControl : Control, IFubuView<TestOutputModel>
        {
            public IModelState StateThatWasSet { get; private set; }

            public TestOutputModel Model { get; set; }

            public void SetModel(IModelState state)
            {
                StateThatWasSet = state;
            }
        }
    }
}
